package com.guli.order.controller;

import com.alipay.api.AlipayApiException;
import com.guli.common.utils.R;
import com.guli.order.service.AliPayService;
import com.guli.order.service.OrderService;
import com.guli.order.vo.AliPayAsyncCallBackVo;
import com.guli.order.vo.AliPayCallBackVo;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/*
 * @Author 罗俊
 * @date 2020/11/27 - 4:22 下午
 *
 */
@Controller
@Slf4j
@RequestMapping("/mall/payment")
public class AliPayController {

    @Resource
    AliPayService aliPayService;

    @Resource
    OrderService orderService;

    /**
     * 因为支付宝返回的是一个html的<form></form>表单，所以直接告诉浏览器响应的数据类型（这样浏览器就不会报警告了）
     * @param orderSn
     * @return
     * @throws InterruptedException
     * @throws ExecutionException
     * @throws AlipayApiException
     */
    @ResponseBody
    @GetMapping(value = "/getOrderInfoAndGoToAliPayment",produces = "text/html")
    @ApiOperation("获取订单信息，并跳转支付宝的支付页面")
    public String getOrderInfoAndGoToAliPayment(@RequestParam("orderSn") String orderSn) throws InterruptedException, ExecutionException, AlipayApiException {

        return aliPayService.getOrderInfoAndGoToAliPayment(orderSn);
    }

    // 支付宝跳回之后，被登陆拦截器拦截了，放行
    @GetMapping("/alipay/afterAliPayment")
    @ApiOperation("支付宝支付完成之后的回调地址")
    public String afterAliPayment( AliPayCallBackVo aliPayCallBackVo,HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
        //TODO 验证签名，如果正确才可以去数据库修改订单的状态
        //TODO 但是可能这里崩溃，就不能去修改订单数据库的状态了
        // 解决方法：使用异步通知

        // 验证签名
        aliPayService.confirmSign(request); // 异步回调中的有些参数没有，会报空指针

        orderService.updatePaymentStatus(aliPayCallBackVo.getOut_trade_no());// 更新订单状态为已支付（已做幂等性处理：只有订单状态是未支付状态，才能更新订单状态为待发货）

        return "redirect:http://order.guli.com/order/index.html";
    }

    /**
     * 异步消息通知还先于同步消息抵达
     *
     * 如果请求参数加上 @RequestBody ，就会 Content type 'application/x-www-form-urlencoded;charset=utf-8' not supported
     *
     * @param request
     * @return
     */
    @PostMapping("/alipay/async/notify")
    @ApiOperation("支付宝支付成功之后的异步通知接口，由支付宝调用")
    @ResponseBody
    public String acceptAsyncNotifyOfAliPay(HttpServletRequest request,/*@RequestBody*/  AliPayAsyncCallBackVo aliPayAsyncCallBackVo) throws Exception {

        Map<String, String[]> parameterMap = request.getParameterMap();

        for (String key : parameterMap.keySet()) {

            Object parameter = request.getParameter(key);

            log.info("支付宝发来异步通知了，参数是：{} = {}",key,parameter);

        }

        log.info("支付宝发来异步通知了，封装好的参数是：{}",aliPayAsyncCallBackVo);

        // 验证签名
        aliPayService.confirmSign(request);

        aliPayService.updatePaymentStatus(aliPayAsyncCallBackVo);

        // 只要我们收到了支付宝给我们的异步通知，告诉我们订单支付成功。就应该返回给支付宝 success，这样支付宝之后就不会再通知了
        return "success";
    }

}
